<template>
  <div ref="echartDom"></div>
</template>

<script setup>
import {ref, defineProps, onMounted, onUnmounted, inject, shallowRef, defineExpose} from 'vue'
import {pxToRem} from "@/utils/index";

const props = defineProps({
  graphData: {
    type: Object,
    default: () => {
    }
  },
  dialogData: {
    type: Object,
    default: () => ({
      fontSizeTimes: 1
    })
  }
});

const echartDom = ref(null);
const myChart = shallowRef(null);
const echarts = inject('echarts');

const initEchart = () => {
  if (echartDom.value) {
    myChart.value = echarts.init(echartDom.value);
    let option = {
      title: {
        show: false,
        text: '产品与购房人关系',
        textStyle: {
          color: 'white',
          fontSize: pxToRem(14 * props?.dialogData?.fontSizeTimes),
          fontWeight: 'normal'
        }
      },
      legend: {
        show: false,
        right: props?.dialogData?.fontSizeTimes === 1 ? 0 : '3%',
        icon: 'rect',
        itemWidth: pxToRem(10 * props?.dialogData?.fontSizeTimes),
        itemHeight: pxToRem(10 * props?.dialogData?.fontSizeTimes),
        textStyle: {
          color: 'white',
          fontSize: pxToRem(12 * props?.dialogData?.fontSizeTimes)
        },
        data: [
          {
            name: '开发商',
            itemStyle: {
              color: '#E65992'
            }
          },
          {
            name: '户型',
            itemStyle: {
              color: '#0E5FFF'
            }
          },
          {
            name: '购房人年龄',
            itemStyle: {
              color: '#01C4D2'
            }
          }
        ]
      },
      xAxis: {
        show: false
      },
      yAxis: {
        show: false
      },
      series: [
        {
          type: "graph",
          left: '0',
          right: '0',
          bottom: '0',
          top: '0',
          zoom: .7,
          // 力引导布局相关的配置项，力引导布局是模拟弹簧电荷模型在每两个节点之间添加一个斥力，每条边的两个节点之间添加一个引力，每次迭代节点会在各个斥力和引力的作用下移动位置，多次迭代后节点会静止在一个受力平衡的位置，达到整个模型的能量最小化。
          force: {
            initLayout: 'circular', // 初始布局
            repulsion: pxToRem(props?.dialogData?.fontSizeTimes == 1 ? 3000 : 8000),       // 节点之间的推荐力
            edgeLength: [pxToRem(150), pxToRem(props?.dialogData?.fontSizeTimes === 1 ? 300 : 1000)],        // 边的长度，即节点之间的距离
            gravity: 0.1,          // 重力，影响节点下落
            friction: 0.1,  // 减缓节点的移动速度。取值范围 0 到 1
            // 是否在布局计算后调整布局，使节点不超出边界
            preventOverlap: true,
            // 布局的容忍系数，0 表示不允许节点与节点之间有任何重叠，1 表示完全允许重叠
            tolerance: 1,
            // 布局的容忍系数，0 表示不允许边与边之间有任何相交，1 表示完全允许边相交
            edgeTolerance: 1
          },
          scaleLimit: {
            min: 0.1,
            max: 2
          },
          // 设置图表的布局中心点，使图表居中
          layoutCenter: ['50%', '50%'],
          // 设置节点之间的距离，防止节点相互之间相互覆盖
          preventOverlap: true,
          roam: true,
          layout: "force",
          symbol: 'circle',
          // 关系对象上的标签
          label: {
            normal: {
              // 是否显示标签
              show: true,
              // 标签位置:'top''left''right''bottom''inside''insideLeft''insideRight''insideTop''insideBottom''insideTopLeft''insideBottomLeft''insideTopRight''insideBottomRight'
              position: "inside",
              // 文本样式
              textStyle: {
                fontSize: pxToRem(10 * props?.dialogData?.fontSizeTimes),
                color: 'white'
              }
            }
          },
          lineStyle: {
            color: "white"
          },
          // 连接两个关系对象的线上的标签
          edgeLabel: {
            normal: {
              show: false,
              textStyle: {
                fontSize: pxToRem(10 * props?.dialogData?.fontSizeTimes),
                color: 'white',
              },
              // 标签内容
              formatter: function (param) {
                return param.data.category;
              }
            }
          },
          // 节点分类的类目，可选。如果节点有分类的话可以通过 data[i].category 指定每个节点的类目，类目的样式会被应用到节点样式上。图例也可以基于categories名字展现和筛选。
          categories: props?.graphData?.seriesData?.categories,
          symbolSize: [pxToRem(60 * props?.dialogData?.fontSizeTimes), pxToRem(60 * props?.dialogData?.fontSizeTimes)], // 关系图节点标记的大小，可以设置成诸如 10 这样单一的数字，也可以用数组分开表示宽和高，例如 [20, 10] 表示标记宽为20，高为10。
          draggable: true, // 节点是否可拖拽，只在使用力引导布局的时候有用。
          cursor: 'pointer',
          data: props?.graphData?.seriesData?.data,
          emphasis: {
            edgeLabel: {
              show: true // 在 hover 时显示边的标签
            }
          },
          // 节点间的关系数据
          links: props?.graphData?.seriesData?.links
        }]
    }
    option && myChart.value.setOption(option, true);

    myChart.value.on("legendselectchanged", (params) => {
      event.stopPropagation();
    });

    myChart.value.on("click", (params) => {
      event.stopPropagation();
    });
  }
}

const updateChart = () => {
  if (myChart.value) {
    myChart.value.dispose(); // 销毁旧图表实例
  }
  initEchart();
};

defineExpose({
  updateChart
})

onMounted(() => {
  initEchart();
  window.addEventListener("resize", updateChart);
})

onUnmounted(() => {
  window.removeEventListener("resize", updateChart);
})
</script>

<style scoped lang="less">
.h275 {
  height: 275px;
}
.dialog-h275 {
  width: 1120px;
  height: 750px;
}
</style>